iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 23
2
Software Development

iOS 三十天上架記帳 APP系列 第 23

Money Mom - 實做統計功能 - 折線圖 Part ∞

  • 分享至 

  • xImage
  •  

這篇專注在處理 Core Data 資料轉換,為了完成真正的折線圖!

Migrate Transactions

  1. 自己在 AppDelegate 判斷,如果有 Transaction 但是沒有 TransactionStats 的話,就要執行 Migration。
  2. 用 Core Data 判斷執行 Policy。

我認為目前方案一不適合,因為要花額外時間做很多時間,只剩下今天能做折線圖了,所以走方案二。

如何讓 Core Data 執行 Policy?

  1. 建立新 Model,並指定其為當前版本
  2. 建立新的 Mapping Model,並設定我們自己建立的 NSEntityMigrationPolicy

如此一來,程式執行後,Core Data 就會偵測 Model 版本,並視需要執行我們的 NSEntityMigrationPolicy。

實做 NSEntityMigrationPolicy

收支記錄統計是依照「天」來統計,所以我們要用當「天」的午夜時間記錄。首先要注意的是時區,系統中所有的日期,都要以 GMT 時間儲存,只有在顯示時轉成使用者的時區,因此我們用 Calendar 轉換成午夜時間時,需注意要設定成 GMT 時間,如下:

let calendar: Calendar = {
    var calendar = Calendar.current
    calendar.timeZone = TimeZone(secondsFromGMT: 0)!
    return calendar
}()

接下來我們在轉換收支記錄時,便可以用下列方式,取得該收支記錄對應的午夜時間:

let midnight = calendar.startOfDay(for: sInstance.value(forKey: "createdAt") as! Date)

接下來再透過這個時間去處理統計資料,如果還沒有統計資料就新增一筆,有該「天」的統計資料就更新金額,如下:

let request = NSFetchRequest<NSManagedObject>(entityName: mapping.destinationEntityName!)
request.predicate = NSPredicate(format: "\(#keyPath(TransactionStats.date)) = %@", argumentArray: [midnight])
guard let transactionStat = try! manager.destinationContext.fetch(request).first(where: {
    return $0.value(forKey: "type") as! TransactionType == sInstance.value(forKey: "type") as! TransactionType
}) else {
    let dInstance = NSEntityDescription.insertNewObject(forEntityName: mapping.destinationEntityName!, into: manager.destinationContext)

    dInstance.setValue(sInstance.value(forKey: "amount"), forKey: "amount")
    dInstance.setValue(midnight, forKey: "date")
    dInstance.setValue(sInstance.value(forKey: "type"), forKey: "type")

    return
}

transactionStat.setValue((sInstance.value(forKey: "amount") as! NSDecimalNumber).adding(transactionStat.value(forKey: "amount") as! NSDecimalNumber), forKey: "amount")

備註:引以為傲的 TransactionType 因為在資料庫中是 Transformable,也就是說在 SQLite 中是二進位,根本沒辦法作為 NSPredicate 的篩選條件,這是一個嚴重的錯誤設計,必須被修正!GitHub Issue

以上實做完成後,再把折線圖的資料換成新的資料即可。

展示

程式碼:Github

之後再安排時間加上 XY 軸的值,下一篇先實做依照標籤篩選收支記錄,即時更新折線圖。


上一篇
Money Mom - 實做統計功能 - 折線圖 Part 1
下一篇
Money Mom - 實做統計功能 - 標籤快篩
系列文
iOS 三十天上架記帳 APP30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言